//*****************************************************************************
//* Foxit Digital Rights Management Library
//*
//* Foxit Software Inc.
//* Copyright(C) 2005-2010, all rights reserved.
//*
//* The following code is copyrighted and contains proprietary information
//* and trade secrets of Foxit Software Inc.
//*****************************************************************************
/**
 * @addtogroup FDRM
 * @{
 */

/**
 * @file
 * @brief Define interfaces, classes & functions for engine.
 */

#ifndef _FDRM_ENGINE
#define _FDRM_ENGINE

//Classes defined in this header
class CFDRM_EncryptionParams;
class IFDRM_EncryptionEngine;
class CFDRM_DecryptionParams;
class IFDRM_DecryptionEngine;
class CFDRM_RecryptionParams;
class IFDRM_RecryptionEngine;

//*****************************************************************************
//* Encryption engine
//*****************************************************************************
/**
 * @name Encryption engine
 */
/*@{*/

/** @brief Constant for GUID of default encryption engine */
const FX_GUID FDRM_ENCRYPTIONENGINE_DefGUID = {0x4772c701, 0xe681, 0x4e2d, {0x92, 0xea, 0x9e, 0xff, 0xcc, 0x2b, 0x66, 0x9f}};
/** @brief Constant for version number of default encryption engine */
const FX_DWORD	FDRM_ENCRYPTIONENGINE_Version = 0x20100731;

/**
 * @brief Data class for encryption parameters
 */
class CFDRM_EncryptionParams : public CFX_Object
{
public:
	/** @brief Default constructor for encryption parameters */
	CFDRM_EncryptionParams() : m_EngineGUID(FDRM_ENCRYPTIONENGINE_DefGUID)
							 , m_dwVersion(FDRM_ENCRYPTIONENGINE_Version)
							 , m_pSeed(NULL)
							 , m_pKeys(NULL)
							 , m_pCryptor(NULL)
							 , m_pSrcData(NULL)
							 , m_pDstData(NULL)
	{
	}

	FX_GUID				m_EngineGUID;	//Engine GUID
	FX_DWORD				m_dwVersion;	//Version of encryption engine
	IFDRM_SeedProvider		*m_pSeed;		//Seed provider
	IFDRM_KeyProvider		*m_pKeys;		//Key provider
	IFDRM_CryptorProvider	*m_pCryptor;	//Cryptor provider
	IFX_FileRead			*m_pSrcData;	//Source data stream
	IFX_FileWrite			*m_pDstData;	//Destination data stream
};

/**
 * @brief Encryption Engine
 */
class IFDRM_EncryptionEngine : public CFDRM_Object
{
public:
	/**
	 * @brief	Start encryption, this method will initialize encryption process.
	 * @return	Return a non-negative value for getting ready;
	 *			Return -1 if encryption engine cannot be used;
	 *			Return -2 if seed provider cannot be used;
	 *			Return -3 if cannot generate encryption key;
	 *			Return -4 if cryptor settings cannot be used;
	 *			Return -5 if source data stream cannot be used;
	 *			Return -6 if destination data stream is not ready;
	 *			Return other negative value if any error occurs.
	 */
	virtual FX_INT32		StartEncryption() = 0;

	/**
	 * @brief	Do encryption in progressive mode.
	 * @param[in] pPause	a pause object if need progressive control, or pass NULL for normal control.
	 * @return	Return any positive value which is less than 100 if the encryption is paused;
	 *			Return 100 or a positive value greater than 100 if the encryption finishes;
	 *			Return any negative value if any error occurs.
	 */
	virtual FX_INT32		DoEncryption(IFX_Pause *pPause = NULL) = 0;
};

/**
 * @brief	Create an instance of default encryption engine.
 * @param[in] params	specifies encryption parameters, should be valid before starting encryption.
 * @return	Return the instance object of default encryption engine. Return NULL if meets any error.
 */
IFDRM_EncryptionEngine*	FDRM_EncryptionEngine_CreateDef(const CFDRM_EncryptionParams &params);

/**
 * @brief	Generate encryption key according to encryption parameters.
 * @param[in] params	specifies encryption parameters, m_pSrcData and m_pDstData are not used.
 * @param[out] bsKey	stores the final encryption key.
 * @return	Return a non-negative value if the key is generated successfully;
 *			Return -1 if encryption engine info cannot be used;
 *			Return -2 if seed provider cannot be used;
 *			Return -3 if encryption sub keys cannot be used;
 *			Return -4 if encryption cryptor settings cannot be used;
 *			Return other negative value if any error occurs.
 */
FX_INT32	FDRM_EncryptionEngine_GenerateKey(const CFDRM_EncryptionParams &params, CFDRM_ByteKeyString &bsKey);

/*@}*/

//*****************************************************************************
//* Decryption engine
//*****************************************************************************
/**
 * @name Decryption engine
 */
/*@{*/

/** @brief Constant for GUID of default decryption engine */
const FX_GUID FDRM_DECRYPTIONENGINE_DefGUID = {0x4772c702, 0xe681, 0x4e2d, {0x92, 0xea, 0x9e, 0xff, 0xcc, 0x2b, 0x66, 0x9f}};
/** @brief Constant for version number of default decryption engine */
const FX_DWORD	FDRM_DECRYPTIONENGINE_Version = 0x20100731;

/**
 * @brief Data class for decryption parameters
 */
class CFDRM_DecryptionParams : public CFX_Object
{
public:
	/** @brief Default constructor for decryption parameters */
	CFDRM_DecryptionParams() : m_EngineGUID(FDRM_DECRYPTIONENGINE_DefGUID)
							 , m_dwVersion(FDRM_DECRYPTIONENGINE_Version)
							 , m_pKeys(NULL)
							 , m_pSeed(NULL)
							 , m_pCryptor(NULL)
							 , m_pSrcData(NULL)
							 , m_pDstData(NULL)
	{
	}

	FX_GUID				m_EngineGUID;	//Engine GUID
	FX_DWORD				m_dwVersion;	//Version of decryption engine
	IFDRM_SeedProvider		*m_pSeed;		//Seed provider
	IFDRM_KeyProvider		*m_pKeys;		//Key provider
	IFDRM_CryptorProvider	*m_pCryptor;	//Cryptor provider
	IFX_FileRead			*m_pSrcData;	//Source data stream
	IFX_FileWrite			*m_pDstData;	//Destination data stream
};

/**
 * @brief Decryption Engine
 */
class IFDRM_DecryptionEngine : public CFDRM_Object
{
public:
	/**
	 * @brief	Start decryption, this method will initialize decryption process.
	 * @return	Return a non-negative value for getting ready;
	 *			Return -1 if decryption engine cannot be used;
	 *			Return -2 if seed provider cannot be used;
	 *			Return -3 if cannot generate decryption key;
	 *			Return -4 if cryptor settings cannot be used;
	 *			Return -5 if source data stream cannot be used;
	 *			Return -6 if destination data stream is not ready;
	 *			Return other negative value if any error occurs.
	 */
	virtual FX_INT32		StartDecryption() = 0;

	/**
	 * @brief	Do decryption in progressive mode. Under this mode, decryption parameter m_pDstData should be valid.
	 * @param[in] pPause	a pause object if need progressive control, or pass NULL for normal control.
	 * @return	Return any positive value which is less than 100 if the decryption is paused;
	 *			Return 100 or a positive value greater than 100 if the decryption finishes;
	 *			Return any negative value if any error occurs.
	 */
	virtual FX_INT32		DoDecryption(IFX_Pause *pPause = NULL) = 0;

	/**
	 * @brief	Do decryption in random mode. Under this mode, decryption parameter m_pDstData is not used.
	 * @param[out] pBuffer		a buffer which receives decrypted data, the buffer size should be not less than dwSize value.
	 * @param[in] dwOffset		the starting offset in source data stream, which specifies the position from that start decryption.
	 * @param[in] dwSize		the size which specifies how many bytes should be decrypted from the startting offset.
	 * @return	Return any positive value which tells the real decrypted size in bytes;
	 *			Return 0 if no data is decrypted;
	 *			Return any negative value if any error occurs.
	 */
	virtual	FX_INT32		DoDecryption(FX_LPBYTE pBuffer, FX_DWORD dwOffset, FX_DWORD dwSize) = 0;
};

/**
 * @brief	Create an instance of default decryption engine.
 * @param[in] params	specifies decryption parameters, should be valid before starting decryption.
 * @return	Return the instance object of default decryption engine. Return NULL if meets any error.
 */
IFDRM_DecryptionEngine*	FDRM_DecryptionEngine_CreateDef(const CFDRM_DecryptionParams &params);

/**
 * @brief	Generate decryption key according to decryption parameters.
 * @param[in] params	specifies decryption parameters, m_pSrcData and m_pDstData are not used.
 * @param[out] bsKey	stores the final decryption key.
 * @return	Return a non-negative value if the key is generated successfully;
 *			Return -1 if decryption engine info cannot be used;
 *			Return -2 if seed provider cannot be used;
 *			Return -3 if decryption sub keys cannot be used;
 *			Return -4 if decryption cryptor settings cannot be used;
 *			Return other negative value if any error occurs.
 */
FX_INT32	FDRM_DecryptionEngine_GenerateKey(const CFDRM_DecryptionParams &params, CFDRM_ByteKeyString &bsKey);

/*@}*/

//*****************************************************************************
//* Re-encryption engine
//*****************************************************************************
/**
 * @name Re-encryption engine
 */
/*@{*/

/**
 * @brief Data class for re-encryption parameters
 */
class CFDRM_RecryptionParams : public CFX_Object
{
public:
	/** @brief Default constructor for re-encryption parameters */
	CFDRM_RecryptionParams() : m_DecryptionEngineGUID(FDRM_DECRYPTIONENGINE_DefGUID)
							 , m_EncryptionEngineGUID(FDRM_ENCRYPTIONENGINE_DefGUID)
							 , m_dwDecryptionVersion(FDRM_DECRYPTIONENGINE_Version)
							 , m_dwEncryptionVersion(FDRM_ENCRYPTIONENGINE_Version)
							 , m_pSeed(NULL)
							 , m_pDecryptionKeys(NULL)
							 , m_pEncryptionKeys(NULL)
							 , m_pDecryptionCryptor(NULL)
							 , m_pEncryptionCryptor(NULL)
							 , m_pSrcData(NULL)
							 , m_pDstData(NULL)
	{
	}

	FX_GUID				m_DecryptionEngineGUID;	//Decryption engine GUID
	FX_GUID				m_EncryptionEngineGUID;	//Encryption engine GUID
	FX_DWORD				m_dwDecryptionVersion;	//Version of decryption engine
	FX_DWORD				m_dwEncryptionVersion;	//Version of encryption engine
	IFDRM_SeedProvider		*m_pSeed;				//Seed provider
	IFDRM_KeyProvider		*m_pDecryptionKeys;		//Decryption Key provider
	IFDRM_KeyProvider		*m_pEncryptionKeys;		//Encryption Key provider
	IFDRM_CryptorProvider	*m_pDecryptionCryptor;	//Decryption cryptor provider
	IFDRM_CryptorProvider	*m_pEncryptionCryptor;	//encryption cryptor provider
	IFX_FileRead			*m_pSrcData;			//Source data stream
 	IFX_FileWrite			*m_pDstData;			//Destination data stream
};

/**
 * @brief Re-encryption Engine
 */
class IFDRM_RecryptionEngine : public CFDRM_Object
{
public:
	/**
	 * @brief	Start re-encryption, this method will initialize re-encryption process.
	 * @return	Return a non-negative value for getting ready;
	 *			Return -1 if decryption engine cannot be used;
	 *			Return -2 if encryption engine cannot be used;
	 *			Return -3 if seed provider cannot be used;
	 *			Return -4 if cannot generate decryption key;
	 *			Return -5 if cannot generate encryption key;
	 *			Return -6 if decryption cryptor settings cannot be used;
	 *			Return -7 if encryption cryptor settings cannot be used;
	 *			Return -8 if source data stream cannot be used;
	 *			Return -9 if destination data stream is not ready;
	 *			Return other negative value if any error occurs.
	 */
	virtual FX_INT32		StartRecryption() = 0;

	/**
	 * @brief	Do re-encryption in progressive mode.
	 * @param[in] pPause	a pause object if need progressive control, or pass NULL for normal control.
	 * @return	Return any positive value which is less than 100 if the re-encryption is paused;
	 *			Return 100 or a positive value greater than 100 if the re-encryption finishes;
	 *			Return any negative value if any error occurs.
	 */
	virtual FX_INT32		DoRecryption(IFX_Pause *pPause = NULL) = 0;
};

/**
 * @brief	Create an instance of default re-encryption engine.
 * @param[in] params	specifies re-encryption parameters, should be valid before starting re-encryption.
 * @return	Return the instance object of default re-encryption engine. Return NULL if meets any error.
 */
IFDRM_RecryptionEngine*	FDRM_RecryptionEngine_CreateDef(const CFDRM_RecryptionParams &params);

/*@}*/

#endif //_FDRM_ENGINE

/** @} */
